<template>
  <div class="page-container">
    <div class="page-content">
      <a-card>
        <!-- 搜索表单 -->
        <div class="search-form">
          <a-form layout="inline" :model="searchForm">
            <a-form-item label="菜单名称">
              <a-input
                v-model:value="searchForm.permissionName"
                placeholder="请输入菜单名称"
                style="width: 200px"
                allow-clear
                @pressEnter="handleSearch"
              />
            </a-form-item>
            <a-form-item label="菜单类型">
              <a-select
                v-model:value="searchForm.type"
                placeholder="请选择菜单类型"
                style="width: 150px"
                allow-clear
              >
                <a-select-option :value="0">目录</a-select-option>
                <a-select-option :value="1">菜单</a-select-option>
                <a-select-option :value="2">按钮</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="状态">
              <a-select
                v-model:value="searchForm.permissionStatus"
                placeholder="请选择状态"
                style="width: 120px"
                allow-clear
              >
                <a-select-option value="enabled">启用</a-select-option>
                <a-select-option value="disabled">禁用</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item>
              <a-button type="primary" @click="handleSearch">
                <SearchOutlined />
                查询
              </a-button>
              <a-button style="margin-left: 8px" @click="handleReset"> 重置 </a-button>
            </a-form-item>
          </a-form>
        </div>

        <!-- 操作按钮 -->
        <div class="table-operations">
          <PermissionButton permission="system:menu:add">
            <a-button type="primary" @click="handleAdd">
              <PlusOutlined />
              新增菜单
            </a-button>
          </PermissionButton>

          <PermissionButton permission="system:menu:expand">
            <a-button @click="toggleExpand">
              <MenuUnfoldOutlined v-if="!isExpanded" />
              <MenuFoldOutlined v-else />
              {{ isExpanded ? '收起全部' : '展开全部' }}
            </a-button>
          </PermissionButton>
        </div>

        <!-- 数据表格 -->
        <a-table
          :columns="columns"
          :data-source="tableData"
          :loading="loading"
          :pagination="false"
          row-key="id"
          :expanded-row-keys="expandedKeys"
          @expand="onExpand"
          :scroll="{ x: 1200 }"
        >
          <!-- 菜单名称列 -->
          <template #permissionName="{ record }">
            <span class="menu-title">
              <DynamicIcon v-if="record.icon" :name="record.icon" style="margin-right: 8px" />
              {{ record.permissionName }}
            </span>
          </template>

          <!-- 菜单类型列 -->
          <template #type="{ record }">
            <a-tag :color="getTypeColor(record.type)">
              {{ getTypeText(record.type) }}
            </a-tag>
          </template>

          <!-- 显示状态列 -->
          <template #show="{ record }">
            <a-tag :color="record.show === 1 ? 'green' : 'red'">
              {{ record.show === 1 ? '显示' : '隐藏' }}
            </a-tag>
          </template>

          <!-- 状态列 -->
          <template #permissionStatus="{ record }">
            <a-tag :color="record.permissionStatus === 'enabled' ? 'green' : 'red'">
              {{ record.permissionStatus === 'enabled' ? '启用' : '禁用' }}
            </a-tag>
          </template>

          <!-- 操作列 -->
          <template #action="{ record }">
            <a-space>
              <PermissionButton permission="system:menu:add">
                <a-button
                  v-if="record.type !== 2"
                  type="link"
                  size="small"
                  @click="handleAddChild(record)"
                >
                  <PlusOutlined />
                  新增
                </a-button>
              </PermissionButton>

              <PermissionButton permission="system:menu:edit">
                <a-button type="link" size="small" @click="handleEdit(record)">
                  <EditOutlined />
                  编辑
                </a-button>
              </PermissionButton>

              <PermissionButton permission="system:menu:delete">
                <a-button type="link" size="small" danger @click="handleDelete(record)">
                  <DeleteOutlined />
                  删除
                </a-button>
              </PermissionButton>
            </a-space>
          </template>
        </a-table>
      </a-card>
    </div>

    <!-- 新增/编辑弹窗 -->
    <a-modal
      v-model:open="modalVisible"
      :title="isEdit ? '编辑菜单' : '新增菜单'"
      width="680px"
      :destroy-on-close="true"
      @ok="handleSubmit"
      @cancel="handleCancel"
    >
      <a-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <a-form-item label="上级菜单" name="parentId">
          <a-tree-select
            v-model:value="formData.parentId"
            :tree-data="menuTreeDataSimple"
            :field-names="{ label: 'permissionName', value: 'id', children: 'children' }"
            placeholder="请选择上级菜单（留空为顶级菜单）"
            :disabled="formData.type === 0"
            allow-clear
            tree-default-expand-all
            show-search
            :filter-tree-node="filterTreeNode"
            tree-node-filter-prop="permissionName"
          >
            <template #title="{ permissionName, type, icon }">
              <span class="tree-select-title" :class="getTypeClassName(type)">
                <DynamicIcon v-if="icon" :name="icon" class="menu-icon" />
                <component v-else :is="getDefaultIcon(type)" class="menu-icon default-icon" />
                <span class="menu-name">{{ permissionName }}</span>
              </span>
            </template>
          </a-tree-select>
          <div v-if="formData.type === 0" style="margin-top: 4px; color: #999; font-size: 12px">
            目录类型默认为顶级菜单，无需选择上级菜单
          </div>
        </a-form-item>

        <a-form-item label="菜单类型" name="type">
          <a-radio-group v-model:value="formData.type" @change="onTypeChange">
            <a-radio :value="0">目录</a-radio>
            <a-radio :value="1">菜单</a-radio>
            <a-radio :value="2">按钮</a-radio>
          </a-radio-group>
        </a-form-item>

        <a-form-item label="菜单名称" name="permissionName">
          <a-input v-model:value="formData.permissionName" placeholder="请输入菜单名称" />
        </a-form-item>

        <a-form-item label="权限标识" name="permissionKey">
          <a-input
            v-model:value="formData.permissionKey"
            placeholder="请输入权限标识，如：system:menu:list"
          />
        </a-form-item>

        <a-form-item v-if="formData.type !== 2" label="菜单图标" name="icon">
          <IconSelector v-model="formData.icon" placeholder="请选择菜单图标" />
        </a-form-item>

        <a-form-item v-if="formData.type === 1" label="路由地址" name="menuUrl">
          <a-input
            v-model:value="formData.menuUrl"
            placeholder="请输入路由地址，如：/system/menu"
          />
        </a-form-item>

        <a-form-item label="排序" name="sort">
          <a-input-number
            v-model:value="formData.sort"
            :min="0"
            :max="9999"
            placeholder="请输入排序号"
            style="width: 100%"
          />
        </a-form-item>

        <a-form-item label="显示状态" name="show">
          <a-radio-group v-model:value="formData.show">
            <a-radio :value="1">显示</a-radio>
            <a-radio :value="0">隐藏</a-radio>
          </a-radio-group>
        </a-form-item>

        <a-form-item label="菜单状态" name="permissionStatus">
          <a-radio-group v-model:value="formData.permissionStatus">
            <a-radio value="enabled">启用</a-radio>
            <a-radio value="disabled">禁用</a-radio>
          </a-radio-group>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import {
  SearchOutlined,
  PlusOutlined,
  MenuUnfoldOutlined,
  MenuFoldOutlined,
  AppstoreOutlined,
  EditOutlined,
  DeleteOutlined,
  FolderOutlined,
  FileOutlined,
  ToolOutlined,
} from '@ant-design/icons-vue'
import { message, Modal } from 'ant-design-vue'
import type { FormInstance } from 'ant-design-vue'
import { permissionService } from '@/api/permission'
import type { Permission, PermissionTree, PermissionPageParams } from '@/types'
import PermissionButton from '@/components/PermissionButton.vue'
import IconSelector from '@/components/IconSelector.vue'
import DynamicIcon from '@/components/DynamicIcon.vue'

// 页面状态
const loading = ref(false)
const modalVisible = ref(false)
const isEdit = ref(false)
const isExpanded = ref(false)
const expandedKeys = ref<number[]>([])

// 表单引用
const formRef = ref<FormInstance>()

// 搜索表单
const searchForm = reactive({
  permissionName: '',
  type: undefined as number | undefined,
  permissionStatus: undefined as string | undefined,
})

// 表格数据
const tableData = ref<PermissionTree[]>([])
const allMenuData = ref<PermissionTree[]>([]) // 存储所有菜单数据用于树选择

// 表单数据
const formData = reactive<Partial<Permission>>({
  id: undefined,
  parentId: undefined,
  permissionName: '',
  permissionKey: '',
  type: 0,
  menuUrl: '',
  icon: '',
  sort: 0,
  show: 1,
  permissionStatus: 'enabled',
})

// 表格列定义
const columns = [
  {
    title: '菜单名称',
    dataIndex: 'permissionName',
    key: 'permissionName',
    width: 250,
    slots: { customRender: 'permissionName' },
  },
  {
    title: '类型',
    dataIndex: 'type',
    key: 'type',
    width: 100,
    slots: { customRender: 'type' },
  },
  {
    title: '权限标识',
    dataIndex: 'permissionKey',
    key: 'permissionKey',
    width: 200,
  },
  {
    title: '路由地址',
    dataIndex: 'menuUrl',
    key: 'menuUrl',
    width: 180,
  },
  {
    title: '排序',
    dataIndex: 'sort',
    key: 'sort',
    width: 80,
  },
  {
    title: '显示状态',
    dataIndex: 'show',
    key: 'show',
    width: 100,
    slots: { customRender: 'show' },
  },
  {
    title: '状态',
    dataIndex: 'permissionStatus',
    key: 'permissionStatus',
    width: 100,
    slots: { customRender: 'permissionStatus' },
  },
  {
    title: '创建时间',
    dataIndex: 'createdTime',
    key: 'createdTime',
    width: 160,
  },
  {
    title: '操作',
    key: 'action',
    width: 200,
    fixed: 'right',
    slots: { customRender: 'action' },
  },
]

// 表单验证规则
const rules = {
  permissionName: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  permissionKey: [{ required: true, message: '请输入权限标识', trigger: 'blur' }],
  type: [{ required: true, message: '请选择菜单类型', trigger: 'change' }],
  menuUrl: [
    {
      required: true,
      message: '请输入路由地址',
      trigger: 'blur',
      validator: (_rule: any, value: string) => {
        if (formData.type === 1 && !value) {
          return Promise.reject('菜单类型必须填写路由地址')
        }
        return Promise.resolve()
      },
    },
  ],
  sort: [
    { required: true, message: '请输入排序号', trigger: 'blur' },
    { type: 'number', min: 0, max: 9999, message: '排序号必须在0-9999之间', trigger: 'blur' },
  ],
  show: [{ required: true, message: '请选择显示状态', trigger: 'change' }],
  permissionStatus: [{ required: true, message: '请选择菜单状态', trigger: 'change' }],
}

// 计算属性：菜单树数据（用于上级菜单选择）- 临时简化版本
const menuTreeDataSimple = computed(() => {
  if (!allMenuData.value || allMenuData.value.length === 0) {
    return []
  }

  // 简化过滤：只过滤按钮类型和自身
  const simpleFilter = (items: PermissionTree[]): PermissionTree[] => {
    if (!items || !Array.isArray(items)) return []

    return items
      .filter((item) => {
        // 过滤掉按钮类型
        if (item.type === 2) return false
        // 过滤掉自身（编辑模式）
        if (isEdit.value && formData.id === item.id) return false
        return true
      })
      .map((item) => ({
        ...item,
        children:
          item.children && item.children.length > 0 ? simpleFilter(item.children) : undefined,
      }))
  }

  const result = simpleFilter(allMenuData.value)

  return result
})

// 数据排序函数 - 按sort字段从小到大排序
const sortTreeData = (data: PermissionTree[]): PermissionTree[] => {
  if (!data || !Array.isArray(data)) return []

  return data
    .sort((a, b) => (a.sort || 0) - (b.sort || 0))
    .map((item) => ({
      ...item,
      children: item.children && item.children.length > 0 ? sortTreeData(item.children) : undefined,
    }))
}

// 获取数据 - 使用getPermissionTree接口
const fetchData = async () => {
  try {
    loading.value = true
    // 直接获取树形结构数据，不需要构建
    const treeData = await permissionService.getPermissionTree()

    // 先设置原始数据
    allMenuData.value = sortTreeData(treeData)

    // 再应用筛选条件
    const filteredData = filterTreeData(allMenuData.value)
    tableData.value = sortTreeData(filteredData)
  } catch (error) {
    console.error('获取菜单数据失败:', error)
    message.error('获取菜单数据失败')
  } finally {
    loading.value = false
  }
}

// 过滤树形数据
const filterTreeData = (data: PermissionTree[]): PermissionTree[] => {
  return data.filter((item) => {
    // 检查当前节点是否符合条件
    let matchesFilter = true

    if (searchForm.permissionName && !item.permissionName.includes(searchForm.permissionName)) {
      matchesFilter = false
    }

    if (searchForm.type !== undefined && item.type !== searchForm.type) {
      matchesFilter = false
    }

    if (searchForm.permissionStatus && item.permissionStatus !== searchForm.permissionStatus) {
      matchesFilter = false
    }

    // 递归过滤子节点
    if (item.children && item.children.length > 0) {
      item.children = filterTreeData(item.children)
      // 如果有子节点匹配，父节点也应该显示
      if (item.children.length > 0) {
        matchesFilter = true
      }
    }

    return matchesFilter
  })
}

// 获取菜单类型文本
const getTypeText = (type: number): string => {
  const typeMap = { 0: '目录', 1: '菜单', 2: '按钮' }
  return typeMap[type as keyof typeof typeMap] || '未知'
}

// 获取菜单类型颜色
const getTypeColor = (type: number): string => {
  const colorMap = { 0: 'blue', 1: 'green', 2: 'orange' }
  return colorMap[type as keyof typeof colorMap] || 'default'
}

// 获取菜单类型样式类名
const getTypeClassName = (type: number): string => {
  const classMap = { 0: 'menu-type-directory', 1: 'menu-type-menu', 2: 'menu-type-button' }
  return classMap[type as keyof typeof classMap] || ''
}

// 获取默认图标
const getDefaultIcon = (type: number) => {
  const iconMap = {
    0: FolderOutlined, // 目录 - 文件夹图标
    1: FileOutlined, // 菜单 - 文件图标
    2: ToolOutlined, // 按钮 - 工具图标
  }
  return iconMap[type as keyof typeof iconMap] || AppstoreOutlined
}

// 展开/收起所有节点
const toggleExpand = () => {
  isExpanded.value = !isExpanded.value
  if (isExpanded.value) {
    const getAllKeys = (data: PermissionTree[]): number[] => {
      let keys: number[] = []
      data.forEach((item) => {
        if (item.children && item.children.length > 0) {
          keys.push(item.id)
          keys = keys.concat(getAllKeys(item.children))
        }
      })
      return keys
    }
    expandedKeys.value = getAllKeys(tableData.value)
  } else {
    expandedKeys.value = []
  }
}

// 处理展开/收起
const onExpand = (expanded: boolean, record: Permission) => {
  if (expanded) {
    expandedKeys.value.push(record.id)
  } else {
    const index = expandedKeys.value.indexOf(record.id)
    if (index > -1) {
      expandedKeys.value.splice(index, 1)
    }
  }
}

// 搜索菜单 - 移除分页逻辑
const handleSearch = async () => {
  try {
    loading.value = true
    // 重新获取数据并应用筛选
    const treeData = await permissionService.getPermissionTree()
    allMenuData.value = sortTreeData(treeData)
    const filteredData = filterTreeData(allMenuData.value)
    tableData.value = sortTreeData(filteredData)
  } catch (error) {
    message.error('获取菜单列表失败')
  } finally {
    loading.value = false
  }
}

// 重置
const handleReset = () => {
  Object.assign(searchForm, {
    permissionName: '',
    type: undefined,
    permissionStatus: undefined,
  })
  fetchData()
}

// 新增
const handleAdd = () => {
  isEdit.value = false
  modalVisible.value = true
  resetForm()
}

// 新增子级
const handleAddChild = (record: Permission) => {
  isEdit.value = false
  modalVisible.value = true
  resetForm()
  formData.parentId = record.id
}

// 编辑
const handleEdit = async (record: Permission) => {
  isEdit.value = true
  modalVisible.value = true

  // 如果allMenuData为空，重新获取数据
  if (!allMenuData.value || allMenuData.value.length === 0) {
    try {
      const treeData = await permissionService.getPermissionTree()
      allMenuData.value = sortTreeData(treeData)
    } catch (error) {
      console.error('重新获取数据失败:', error)
    }
  }

  // 深拷贝记录数据，确保parentId正确设置
  const editData = {
    ...record,
    // 确保parentId是正确的数值类型，如果是null则设为undefined
    parentId: record.parentId === null ? undefined : record.parentId,
    // 确保sort字段有默认值
    sort: record.sort ?? 0,
  }

  Object.assign(formData, editData)

  // 如果是目录类型，清空parentId
  if (formData.type === 0) {
    formData.parentId = undefined
  }
}

// 删除
const handleDelete = (record: Permission) => {
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除菜单"${record.permissionName}"吗？删除后不可恢复！`,
    okText: '确定',
    okType: 'danger',
    cancelText: '取消',
    onOk: async () => {
      try {
        await permissionService.deletePermission(record.id)
        message.success('删除成功')
        fetchData()
      } catch (error) {
        message.error('删除失败')
      }
    },
  })
}

// 菜单类型变化处理
const onTypeChange = () => {
  // 清空路由地址（只有菜单类型才需要）
  if (formData.type !== 1) {
    formData.menuUrl = ''
  }
  // 清空图标（按钮类型不需要图标）
  if (formData.type === 2) {
    formData.icon = ''
  }
  // 如果切换为目录类型，清空上级菜单
  if (formData.type === 0) {
    formData.parentId = undefined
  }
}

// 提交表单
const handleSubmit = async () => {
  try {
    await formRef.value?.validate()

    const submitData = { ...formData }

    if (isEdit.value) {
      await permissionService.updatePermission(submitData)
      message.success('编辑成功')
    } else {
      delete submitData.id
      await permissionService.addPermission(submitData)
      message.success('新增成功')
    }

    modalVisible.value = false
    fetchData()
  } catch (error) {
    message.error('操作失败')
  }
}

// 取消弹窗
const handleCancel = () => {
  modalVisible.value = false
  resetForm()
}

// 重置表单
const resetForm = () => {
  Object.assign(formData, {
    id: undefined,
    parentId: undefined,
    permissionName: '',
    permissionKey: '',
    type: 0,
    menuUrl: '',
    icon: '',
    sort: 0,
    show: 1,
    permissionStatus: 'enabled',
  })
  formRef.value?.resetFields()
}

// 树形选择器搜索过滤
const filterTreeNode = (inputValue: string, treeNode: any): boolean => {
  return treeNode.permissionName.toLowerCase().includes(inputValue.toLowerCase())
}

// 检查某个节点是否是指定ID的后代节点
const isDescendant = (node: PermissionTree, targetId: number | undefined): boolean => {
  if (!targetId || !node.children) return false

  for (const child of node.children) {
    if (child.id === targetId) {
      return true
    }
    if (isDescendant(child, targetId)) {
      return true
    }
  }

  return false
}

// 组件挂载时获取数据
onMounted(() => {
  fetchData()
})
</script>

<style scoped lang="scss">
.page-container {
  padding: 24px;

  .page-content {
    .search-form {
      margin-bottom: 16px;
      padding: 16px;
      background: #fafafa;
      border-radius: 6px;
    }

    .table-operations {
      margin-bottom: 16px;
      display: flex;
      gap: 8px;
    }
  }
}

.menu-title {
  display: flex;
  align-items: center;

  .anticon {
    color: #666;
  }
}

:deep(.ant-table-thead > tr > th) {
  background: #fafafa;
  font-weight: 600;
}

:deep(.ant-table-tbody > tr > td) {
  padding: 12px 16px;
}

:deep(.ant-table-row-expand-icon) {
  color: #1890ff;
}

:deep(.ant-btn-link) {
  padding: 0;
  height: auto;
  border: none;
  box-shadow: none;
}

.tree-select-title {
  display: flex;
  align-items: center;
  padding: 2px 4px;
  border-radius: 4px;
  transition: all 0.2s ease;

  .menu-icon {
    margin-right: 8px;
    font-size: 14px;

    &.default-icon {
      opacity: 0.8;
      font-size: 16px;
    }
  }

  .menu-name {
    font-size: 14px;
    font-weight: 500;
  }

  &.menu-type-directory {
    .menu-icon {
      color: #1890ff;
    }

    .menu-name {
      color: #1890ff;
    }
  }

  &.menu-type-menu {
    .menu-icon {
      color: #52c41a;
    }

    .menu-name {
      color: #52c41a;
    }
  }

  &.menu-type-button {
    .menu-icon {
      color: #fa8c16;
    }

    .menu-name {
      color: #fa8c16;
    }
  }

  &:hover {
    background-color: #f5f5f5;
  }
}
</style> 